# -*- coding: utf-8 -*-
# created on 2017/02/22

from sympy import sympify, Abs, S, Intersection, sign
from mathsolver.functions.base import BaseFunction, BaseIneq, BaseSymbolValue, BaseVariable
from mathsolver.functions.hanshu.helper import check_inter, yizhizhiyu_qiufanwei
from mathsolver.functions.hanshu.zhouqi import has_f
from mathsolver.functions.mathematica.mathematicaSolve import MathematicaSolve
from mathsolver.functions.sympy_utils import get_all_child, default_symbol
from sympy import solve


def _def_func(jiou, inter, dandiao, f_io=None):
    """根据奇偶性、区间、单调性，设出函数表达式
    :param jiou 奇偶性
    :param inter 给定区间
    :param dandiao 单调性
    :param f_io [i, o] where f(i) = o"""
    x = sympify('x')

    # 奇函数
    if "奇" in jiou:
        # 区间包含 0
        if 0 in inter:
            # 当 f(x) 过定点时
            if f_io is not None:
                # 根据 f_io 求出 a 的值, a*i = o => a = o / i
                a = sympify('%s / %s' % (f_io[1], f_io[0]))
                fx = a * x
            # f(x) 不过定点
            else:
                fuhao = 1 if "增" in dandiao else -1
                fx = fuhao * x

        # 区间不包含 0
        else:
            fuhao = 1 if "增" in dandiao else -1
            m = sympify('m')
            fx = fuhao * x + sign(x) * m
            real_m = solve(fx.subs(x, f_io[0]) - f_io[1])[0]
            fx = fx.subs(m, real_m)

    # 偶函数
    else:
        fuhao = 1 if "增" in dandiao else -1
        if f_io is None:
            fx = fuhao * Abs(x)
        else:
            m = f_io[1] - fuhao * Abs(f_io[0])
            fx = fuhao * Abs(x) + m

    return fx


def jiou_dandiao_budengshi(jiou, dingyiyu, inter, dandiao, f_io, budengshi):
    """
    函数奇偶性单调性解不等式
    """
    x = sympify('x')
    fx = _def_func(jiou, inter, dandiao, f_io)

    left, op, right = budengshi
    expr = left - right
    fs = get_all_child(expr, has_f)  # f(*)

    fanweis = []
    for f in fs:
        f_arg = f.args[0]
        # f_arg ∈ dingyiyu 求 x 范围
        if dingyiyu != S.Reals and f_arg.has(x):
            fanweis.append(yizhizhiyu_qiufanwei(f_arg, dingyiyu))
        # f(*) 用 fx 替换
        expr = expr.subs(f, fx.subs(x, f_arg))

    var = default_symbol(expr)

    # 解不等式
    ineq_solve = MathematicaSolve().solver(BaseIneq([str(expr), op, 0]), BaseVariable(var)).output[0].value.values()[0]

    if fanweis:
        fanweis.append(ineq_solve)
        # 定义域和不等式解得交集
        res = Intersection(fanweis)
    else:
        res = ineq_solve
    return res


class JiOuDanDiaoJieBuDengShi(BaseFunction):
    def solver(self, *args):
        # 处理输入
        jiou, dingyiyu, interval, dandiao, f_io, ineq = args

        dingyiyu, interval = check_inter(dingyiyu), interval
        if f_io is not None:
            f_io = [f_io.var, f_io.expression]

        left, op, right = ineq.value
        budengshi = [sympify(left), op, sympify(right)]

        res = jiou_dandiao_budengshi(jiou, dingyiyu, interval, dandiao, f_io, budengshi)
        self.output.append(BaseSymbolValue({sympify('x'): res}))
        self.label.add("函数奇偶性与单调性解不等式")
        return self


if __name__ == '__main__':
    pass
    # print "======== 根据奇偶性、区间、单调性，设出函数表达式 ========="
    # print _def_func("奇函数", Interval(0 ,1), "增")
    # print _def_func("奇函数", Interval(0 ,1), "减")
    # print _def_func("奇函数", Interval(0 ,1), "增", [1, 2])
    # print _def_func("奇函数", Interval(0 ,1), "减", [1, 2])
    # print _def_func("奇函数", Interval(0 ,1, True, True), "增", [1, 2])
    # print _def_func("奇函数", Interval(0 ,1, True, True), "减", [1, 2])
    #
    # print _def_func("偶函数", Interval(0 ,1), "增")
    # print _def_func("偶函数", Interval(0 ,1), "减")
    # print _def_func("偶函数", Interval(0 ,1), "增", [1, 2])
    # print _def_func("偶函数", Interval(0 ,1), "减", [1, 2])

    # print "======== 根据奇偶性、单调性，解不等式 ========="
    # print jiou_dandiao_budengshi("偶函数", S.Reals, Interval(0, oo), "增",
    #                              None, [sympify('f(1)'), '<', sympify('f(log(x))')])
    #
    # print jiou_dandiao_budengshi("偶函数", S.Reals, Interval(-oo, 0), "减",
    #                              [-3, 0], [sympify('x*(f(x) + f(-x))'), '<', 0])

    # print "======== 根据奇偶性、单调性，解不等式 ========="
    # # 317921
    # print jiou_dandiao_jiebudengshi().solver(
    #     '偶', S.Reals, Interval(0, oo), '增',
    #     None,
    #     BaseIneq(['f(1)', '<', 'f(log(x))'])).output[0].value
    #
    # # 569626
    # print jiou_dandiao_jiebudengshi().solver(
    #     '奇', S.Reals, Interval(0, 2), '减',
    #     None,
    #     BaseIneq(['f(m) + f(m-1)', '>', '0'])).output[0].value
    #
    # # 669143
    # print jiou_dandiao_jiebudengshi().solver(
    #     '偶', S.Reals, Interval(-oo, 0), '减',
    #     BaseFunc({"var": "1", "name": "f", "type": " ", "expression": "0"}),
    #     BaseIneq(['f(log((1/2)*x))', '>', '0'])).output[0].value
    #
    # # 第四类
    # print jiou_dandiao_jiebudengshi().solver(
    #     '偶', S.Reals, Interval(0, oo), '增',
    #     BaseFunc({"var": "3", "name": "f", "type": " ", "expression": "0"}),
    #     BaseIneq(['f(x) + f(-x)', '<', '0'])).output[0].value
    #
    # # 19320
    # print jiou_dandiao_jiebudengshi().solver(
    #     '偶', S.Reals, Interval(-oo, 0), '减',
    #     BaseFunc({"var": "-3", "name": "f", "type": " ", "expression": "0"}),
    #     BaseIneq(['x*(f(x) + f(-x))', '<', '0'])).output[0].value
